package com.itheima.d1_create_thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/*
    多线程的第三种创建方式：利用Callable接口、FutureTask类来实现。

    实现步骤
        1 创建任务对象
            定义一个类实现Callable接口，重写call方法，封装要做的事情，和要返回的数据。
            把Callable类型的对象封装成FutureTask（线程任务对象）。
        2 把线程任务对象交给Thread对象。
        3 调用Thread对象的start方法启动线程。
        4 线程执行完毕后、通过FutureTask对象的的get方法去获取线程任务执行的结果。

    方式三优缺点：
        优点：线程任务类只是实现接口，可以继续继承类和实现接口，扩展性强；可以在线程执行完毕后去获取线程执行的结果。
        缺点：编码复杂一点。

 */
public class ThreadDemo3 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 3 创建任务类对象
        MyCallable callable = new MyCallable();
        // 4 定义一个桥梁 , 可以链接任务和线程
        FutureTask<String> task = new FutureTask<>(callable);
        // 5 创建一个线程(Thread类)对象
        Thread thread = new Thread(task);

        // 6 开启线程
        thread.start();


        // 在main线程中打印1-10
        for (int i = 1; i <= 10; i++) {
            System.out.println("main线程中打印数据:" + i);
        }

        // 7 获取线程执行完毕的返回值结果
        // get方法具备阻塞作用!
        String result = task.get();// 死等!
        System.out.println("result = " + result);

    }
}

// 1 定义自定义任务类实现Callable接口
class MyCallable implements Callable<String> {
    // 2 需要重写接口中的call方法. 在方法中就可以定义任务
    @Override
    public String call() throws Exception {
        for (int i = 1; i <= 10; i++) {
            System.out.println("新线程打印数据:" + i);
        }
        return "新线程执行完毕!";
    }
}
